#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Weverything"
#pragma clang diagnostic warning "-Wextra"
#pragma clang diagnostic warning "-Wall"
#include "recorder.napi.h"
#include "recorder.user.hpp"
#include "taihe/array.hpp"
#include "recorder.Response.napi.impl.h"
inline bool _taihe_get_msb(uint64_t dig) {
    return dig >> (sizeof(uint64_t) * 8 - 1) != 0;
}
inline bool _taihe_get_sign(taihe::array_view<uint64_t> num) {
    return _taihe_get_msb(num[num.size() - 1]);
}
inline std::pair<bool, taihe::array<uint64_t>> _taihe_get_sign_and_abs(taihe::array_view<uint64_t> num) {
    uint64_t *buf = reinterpret_cast<uint64_t *>(malloc(num.size() * sizeof(uint64_t)));
    bool sign = _taihe_get_msb(num[num.size() - 1]);
    if (sign) {
        bool carry = true;
        for (std::size_t i = 0; i < num.size(); i++) {
            buf[i] = ~num[i] + carry;
            carry = carry && (buf[i] == 0);
        }
    } else {
        for (std::size_t i = 0; i < num.size(); i++) {
            buf[i] = num[i];
        }
    }
    std::size_t size = num.size();
    while (size > 0 && buf[size - 1] == 0) {
        size--;
    }
    return {sign, taihe::array<uint64_t>(buf, size)};
}
inline taihe::array<uint64_t> _taihe_build_num(bool sign, taihe::array_view<uint64_t> abs) {
    uint64_t *buf = reinterpret_cast<uint64_t *>(malloc((abs.size() + 1) * sizeof(uint64_t)));
    if (sign) {
        bool carry = true;
        for (std::size_t i = 0; i < abs.size(); i++) {
            buf[i] = ~abs[i] + carry;
            carry = carry && (buf[i] == 0);
        }
        buf[abs.size()] = carry - 1;
    } else {
        for (std::size_t i = 0; i < abs.size(); i++) {
            buf[i] = abs[i];
        }
        buf[abs.size()] = 0;
    }
    std::size_t size = abs.size() + 1;
    while (size >= 2 && ((buf[size - 1] == 0 && _taihe_get_msb(buf[size - 2]) == 0) ||
                        (buf[size - 1] == static_cast<uint64_t>(-1) && _taihe_get_msb(buf[size - 2]) == 1))) {
        size--;
    }
    return taihe::array<uint64_t>(buf, size);
}
static napi_value recorder_initNative_NAPI(napi_env env, [[maybe_unused]] napi_callback_info info) {
    size_t argc = 7;
    napi_value args[7] = {nullptr};
    NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args , nullptr, nullptr));
    int32_t value0_tmp;
    NAPI_CALL(env, napi_get_value_int32(env, args[0], &value0_tmp));
    int32_t value0 = value0_tmp;
    size_t value1_len = 0;
    NAPI_CALL(env, napi_get_value_string_utf8(env, args[1], nullptr, 0, &value1_len));
    TString value1_abi;
    char* value1_buf = tstr_initialize(&value1_abi, value1_len + 1);
    NAPI_CALL(env, napi_get_value_string_utf8(env, args[1], value1_buf, value1_len + 1, &value1_len));
    value1_buf[value1_len] = '\0';
    value1_abi.length = value1_len;
    taihe::string value1(value1_abi);
    int32_t value2_tmp;
    NAPI_CALL(env, napi_get_value_int32(env, args[2], &value2_tmp));
    int32_t value2 = value2_tmp;
    int32_t value3_tmp;
    NAPI_CALL(env, napi_get_value_int32(env, args[3], &value3_tmp));
    int32_t value3 = value3_tmp;
    double value4_tmp;
    NAPI_CALL(env, napi_get_value_double(env, args[4], &value4_tmp));
    double value4 = value4_tmp;
    int32_t value5_tmp;
    NAPI_CALL(env, napi_get_value_int32(env, args[5], &value5_tmp));
    int32_t value5 = value5_tmp;
    int64_t value6_tmp;
    NAPI_CALL(env, napi_get_value_int64(env, args[6], &value6_tmp));
    int64_t value6 = value6_tmp;
    uintptr_t value = recorder::initNative(value0, value1, value2, value3, value4, value5, value6);
    napi_value result = (napi_value)value;
    return result;
}
static napi_value recorder_startNative_NAPI(napi_env env, [[maybe_unused]] napi_callback_info info) {
    recorder::startNative();
    napi_value result = nullptr;
    napi_get_undefined(env, &result);
    return result;
}
static napi_value recorder_stopNative_NAPI(napi_env env, [[maybe_unused]] napi_callback_info info) {
    uintptr_t value = recorder::stopNative();
    napi_value result = (napi_value)value;
    return result;
}
inline void recorder_Response_create(napi_env env, [[maybe_unused]] napi_value exports) {
    napi_value result = nullptr;
    napi_property_descriptor desc[] = {
        {"code", nullptr, nullptr, recorder_Response_code_getter, recorder_Response_code_setter, nullptr, napi_default, nullptr}, 
        {"surfaceId", nullptr, nullptr, recorder_Response_surfaceId_getter, recorder_Response_surfaceId_setter, nullptr, napi_default, nullptr}, 
    };
    NAPI_CALL(env, napi_define_class(env, "Response_inner", NAPI_AUTO_LENGTH, recorder_Response_constructor_inner, nullptr, sizeof(desc) / sizeof(desc[0]), desc, &result));
    NAPI_CALL(env, napi_create_reference(env, result, 1, &ctor_ref_recorder_Response_t_inner()));
    return;
}
EXTERN_C_START
napi_value Init__recorder(napi_env env, napi_value exports) {
    if (::taihe::get_env() == nullptr) {
        ::taihe::set_env(env);
    }
    recorder_Response_create(env, exports);
    napi_property_descriptor desc[] = {
        {"initNative", nullptr, recorder_initNative_NAPI, nullptr, nullptr, nullptr, napi_default, nullptr}, 
        {"startNative", nullptr, recorder_startNative_NAPI, nullptr, nullptr, nullptr, napi_default, nullptr}, 
        {"stopNative", nullptr, recorder_stopNative_NAPI, nullptr, nullptr, nullptr, napi_default, nullptr}, 
    };
    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
    return exports;
}
EXTERN_C_END
#pragma clang diagnostic pop
